import { createSingletonPromise } from '@vueuse/core'
import neo4j from 'neo4j-driver'

const NEO4J_URI = import.meta.env.VITE_NEO4J_URI || 'bolt://localhost:7474'
const NEO4J_USER = import.meta.env.VITE_NEO4J_USER || 'neo4j'
const NEO4J_PASSWORD = import.meta.env.VITE_NEO4J_PASSWORD || '135672580'

export const useNeo4j = createSingletonPromise(async () => {
  const driver = neo4j.driver(
    NEO4J_URI,
    neo4j.auth.basic(NEO4J_USER, NEO4J_PASSWORD)
  )

  try {
    const serverInfo = await driver.getServerInfo()
    console.log('Neo4j连接成功:', serverInfo)
    return driver
  } catch (error) {
    console.error('Neo4j连接失败:', error)
    throw new Error(`无法连接Neo4j: ${error.message}`)
  }
})

export async function runQuery(query, params = {}) {
  const driver = await useNeo4j()
  const session = driver.session()

  try {
    const result = await session.run(query, params)
    return result.records.map(record => {
      const obj = record.toObject()

      // 转换Neo4j特殊类型为普通JS类型
      const convertNeo4jTypes = (value) => {
        if (neo4j.isInt(value)) return value.toNumber()
        if (value instanceof neo4j.types.Node) {
          return {
            type: 'node',
            identity: value.identity.toNumber(),
            labels: value.labels,
            properties: Object.fromEntries(
              Object.entries(value.properties).map(([k, v]) => [k, convertNeo4jTypes(v)])
            )
          }
        }
        if (value instanceof neo4j.types.Relationship) {
          return {
            type: 'relationship',
            identity: value.identity.toNumber(),
            start: value.start.toNumber(),
            end: value.end.toNumber(),
            type: value.type,
            properties: Object.fromEntries(
              Object.entries(value.properties).map(([k, v]) => [k, convertNeo4jTypes(v)])
            )
          }
        }
        if (Array.isArray(value)) return value.map(convertNeo4jTypes)
        if (value !== null && typeof value === 'object') {
          return Object.fromEntries(
            Object.entries(value).map(([k, v]) => [k, convertNeo4jTypes(v)])
          )
        }
        return value
      }

      return Object.fromEntries(
        Object.entries(obj).map(([key, value]) => [key, convertNeo4jTypes(value)])
      )
    })
  } catch (error) {
    console.error('查询执行失败:', error)
    throw new Error(`查询执行失败: ${error.message}`)
  } finally {
    await session.close().catch(e => console.warn('关闭会话时出错:', e))
  }
}
